home *** CD-ROM | disk | FTP | other *** search
/ Complete Linux / Complete Linux.iso / docs / apps / database / postgres / postgre4.z / postgre4 / src / rules / stubs / stubutil.c < prev   
Encoding:
C/C++ Source or Header  |  1992-08-27  |  8.1 KB  |  358 lines

  1. /*======================================================================
  2.  *
  3.  * FILE:
  4.  * stubutil.c
  5.  *
  6.  * IDENTIFICATION
  7.  * $Header: /private/postgres/src/rules/stubs/RCS/stubutil.c,v 1.9 1991/11/18 22:22:25 mer Exp $
  8.  *
  9.  * DESCRIPTION:
  10.  * 
  11.  * some general utility routines for the world famous 'stub records'
  12.  *
  13.  *======================================================================
  14.  */
  15.  
  16. #include <stdio.h>
  17. #include <strings.h>
  18. #include "utils/log.h"
  19. #include "utils/palloc.h"
  20. #include "tmp/postgres.h"
  21. #include "tmp/datum.h"
  22. #include "rules/prs2.h"
  23. #include "rules/prs2stub.h"
  24. #include "nodes/primnodes.h"
  25. #include "nodes/primnodes.a.h"
  26.  
  27. extern Node CopyObject();
  28. extern bool _equalLispValue();
  29.  
  30. /*-------------------------------------------------------------------
  31.  *
  32.  * prs2StubQualIsEqual
  33.  *
  34.  * Returns true if the two stub qualifications given are
  35.  * equal.
  36.  *
  37.  * NOTE: see restrictions in 'datumIsEqual' for testing whether
  38.  * two datums are equal...
  39.  *
  40.  *-------------------------------------------------------------------
  41.  */
  42. bool
  43. prs2StubQualIsEqual(q1, q2)
  44. LispValue q1;
  45. LispValue q2;
  46. {
  47.     if (_equalLispValue(q1, q2))
  48.     return(true);
  49.     else
  50.     return(false);
  51. }
  52.  
  53. /*-------------------------------------------------------------------
  54.  *
  55.  * prs2OneStubIsEqual
  56.  *
  57.  * return true if the two 'Prs2OneStub's are the same
  58.  *
  59.  * NOTE1: we don't check the 'counter' field
  60.  * NOTE2: we don't check the 'lock' field either, because if
  61.  * 2 stub records have the same 'ruleId' and 'stubId' they are
  62.  * guaranteed to have the same lock!
  63.  *-------------------------------------------------------------------
  64.  */
  65. bool
  66. prs2OneStubIsEqual(stub1, stub2)
  67. Prs2OneStub stub1;
  68. Prs2OneStub stub2;
  69. {
  70.     int i;
  71.  
  72.     if (stub1->ruleId != stub2->ruleId) {
  73.     return(false);
  74.     }
  75.     if (stub1->stubId != stub2->stubId) {
  76.     return(false);
  77.     }
  78.  
  79.     /*
  80.      * Test the qualifications...
  81.      */
  82.     if (!prs2StubQualIsEqual(stub1->qualification, stub2->qualification)) {
  83.     return(false);
  84.     }
  85.  
  86.     return(true);
  87. }
  88.  
  89. /*-------------------------------------------------------------------
  90.  *
  91.  * prs2SearchStub
  92.  *
  93.  * Given a 'Prs2Stub' search and return he index to the 'Prs2OneStub' which
  94.  * is equal to the given 'Prs2OneStub'
  95.  * If no such 'Prs2OneStub; exists, then return -1
  96.  *
  97.  *-------------------------------------------------------------------
  98.  */
  99. int
  100. prs2SearchStub(stubs, oneStub)
  101. Prs2Stub stubs;
  102. Prs2OneStub oneStub;
  103. {
  104.     int i;
  105.     for (i=0; i<stubs->numOfStubs; i++) {
  106.     if (prs2OneStubIsEqual(oneStub, stubs->stubRecords[i])) {
  107.         /*
  108.          * We've found it! Return its index
  109.          */
  110.         return(i);
  111.     }
  112.     }
  113.     /*
  114.      * Nop! We didn't find it!
  115.      */
  116.     return(-1);
  117. }
  118.  
  119. /*-------------------------------------------------------------------
  120.  *
  121.  * prs2AddOneStub
  122.  *
  123.  * Add a new stub record.
  124.  * Note that it is possible to have many copies of the same
  125.  * stub record. Therefore before phusically appending the new stub,
  126.  * see if a similar copy already exists. If yes, then
  127.  * just increment the appropriate counter.
  128.  *
  129.  * NOTE: We do NOT make a copy of the 'newStub'. So do NOT pfree
  130.  * anything contained in there !
  131.  *-------------------------------------------------------------------
  132.  */
  133. void
  134. prs2AddOneStub(oldStubs, newStub)
  135. Prs2Stub oldStubs;
  136. Prs2OneStub newStub;
  137. {
  138.     int i;
  139.     Prs2OneStub s;
  140.     int indx;
  141.     Prs2OneStub *temp;
  142.     int n;
  143.  
  144.     /*
  145.      * does this stub already exist ?
  146.      */
  147.     indx = prs2SearchStub(oldStubs, newStub);
  148.     if (indx >=0) {
  149.     /*
  150.      * this record already exists.
  151.      * Increment its counter and return
  152.      */
  153.     oldStubs->stubRecords[i]->counter += 1;
  154.     return;
  155.     }
  156.     /*
  157.      * this stub record did not exist. We must create a
  158.      * completely new entry...
  159.      * NOTE: 'Prs2Stub->stubRecords' is an array of POINTERS to
  160.      * the 'Prs2OneStubData' records.
  161.      */
  162.     n = oldStubs->numOfStubs;
  163.     temp = (Prs2OneStub *) palloc((n+1) * sizeof(Prs2OneStub));
  164.     for (i=0; i<n; i++) {
  165.     temp[i] = oldStubs->stubRecords[i];
  166.     }
  167.     temp[n] = newStub;
  168.     /*
  169.      * pfree the old array of pointers and replace it with the
  170.      * new one 'temp'.
  171.      */
  172.     if (oldStubs->numOfStubs > 0 && oldStubs->stubRecords != NULL)
  173.     pfree((Pointer)oldStubs->stubRecords);
  174.     oldStubs->stubRecords = temp;
  175.     oldStubs->numOfStubs+= 1;
  176.  
  177. }
  178.  
  179. /*-------------------------------------------------------------------
  180.  *
  181.  * prs2DeleteOneStub
  182.  *
  183.  * Delete a stub record.
  184.  *-------------------------------------------------------------------
  185.  */
  186. void
  187. prs2DeleteOneStub(oldStubs, oldStub)
  188. Prs2Stub oldStubs;
  189. Prs2OneStub oldStub;
  190. {
  191.     int i;
  192.     Prs2OneStub s;
  193.     int n;
  194.     int indx;
  195.  
  196.     /*
  197.      * does this stub already exist ?
  198.      */
  199.     indx = prs2SearchStub(oldStubs, oldStub);
  200.     if (indx < 0) {
  201.     /*
  202.      * No such record existed. complain!
  203.      */
  204.     elog(WARN,"prs2DeleteOneStub: stub not found");
  205.     }
  206.  
  207.     /*
  208.      * So, this record already existed.
  209.      * Decrement its counter.
  210.      */
  211.     s = oldStubs->stubRecords[i];
  212.     (s->counter)--;
  213.  
  214.     /*
  215.      * if the counter is non zero, we are done
  216.      */
  217.     if (s->counter > 0) {
  218.     return;
  219.     }
  220.  
  221.     /*
  222.      * else we must physically delete this record
  223.      * 
  224.      * Move the pointer entry of the last stub record to the one to be
  225.      * deleted and decrement the number of stub records.
  226.      * Don't forget to free the 'oneStub'
  227.      */
  228.     n = oldStubs->numOfStubs;
  229.     pfree((Pointer)oldStubs->stubRecords[indx]);
  230.     oldStubs->stubRecords[indx] = oldStubs->stubRecords[n-1];
  231.     oldStubs->numOfStubs -= 1;
  232.  
  233. }
  234.  
  235. /*-----------------------------------------------------------------------
  236.  *
  237.  * prs2MakeStub
  238.  *
  239.  * create an (empty) stub record
  240.  *
  241.  *-----------------------------------------------------------------------
  242.  */
  243. Prs2Stub
  244. prs2MakeStub()
  245. {
  246.     Prs2Stub res;
  247.  
  248.     res = (Prs2Stub) palloc(sizeof(Prs2StubData));
  249.     if (res == NULL) {
  250.     elog(WARN, "prs2MakeStub: Out of memory\n");
  251.     }
  252.     res->numOfStubs = 0;
  253.     res->stubRecords = NULL;
  254.  
  255.     return(res);
  256. }
  257.  
  258. /*-----------------------------------------------------------------------
  259.  *
  260.  * prs2MakeOneStub
  261.  *
  262.  * create an initialized Prs2OneStub record.
  263.  *
  264.  *-----------------------------------------------------------------------
  265.  */
  266. Prs2OneStub
  267. prs2MakeOneStub()
  268. {
  269.     Prs2OneStub res;
  270.  
  271.     res = (Prs2OneStub) palloc(sizeof(Prs2OneStubData));
  272.     if (res == NULL) {
  273.     elog(WARN, "prs2MakeOneStub: Out of memory\n");
  274.     }
  275.  
  276.     return(res);
  277. }
  278.  
  279. /*-----------------------------------------------------------------------
  280.  *
  281.  * prs2FreeStub
  282.  *
  283.  * free all space occupied by a stub record
  284.  *-----------------------------------------------------------------------
  285.  */
  286. void
  287. prs2FreeStub(relstub)
  288. Prs2Stub relstub;
  289. {
  290.     int i,j;
  291.     Prs2OneStub oneStub;
  292.  
  293.     Assert(PointerIsValid(relstub));
  294.  
  295.     /*
  296.      * One by one free all the 'Prs2OneStub' structs.
  297.      */
  298.     for (i=0; i<relstub->numOfStubs; i++) {
  299.     oneStub = relstub->stubRecords[i];
  300. #ifdef STUB_DEBUG
  301.     bzero(oneStub, sizeof(Prs2OneStubData));
  302. #endif STUB_DEBUG
  303.     pfree((Pointer)oneStub);
  304.     }
  305.  
  306.     if (relstub->numOfStubs>0 && relstub->stubRecords != NULL) {
  307.     pfree((Pointer)relstub->stubRecords);
  308.     }
  309.  
  310. #ifdef STUB_DEBUG
  311.     bzero(relstub, sizeof(Prs2StubData));
  312. #endif STUB_DEBUG
  313.     pfree((Pointer)relstub);
  314. }
  315.  
  316. /*----------------------------------------------------------------------
  317.  * prs2RemoveStubsOfRule
  318.  *
  319.  * Remove the stubs of the given rule (in place).
  320.  * If no stubs of this rule were found return false, else true.
  321.  *----------------------------------------------------------------------
  322.  */
  323. bool
  324. prs2RemoveStubsOfRule(stubs, ruleId)
  325. Prs2Stub stubs;
  326. ObjectId ruleId;
  327. {
  328.     int i;
  329.     Prs2OneStub thisStub;
  330.     bool result;
  331.  
  332.     result = false;
  333.     i=0;
  334.     while (i<stubs->numOfStubs) {
  335.     thisStub = stubs->stubRecords[i];
  336.     if (thisStub->ruleId == ruleId) {
  337.         /*
  338.          * remove this stub by copying over it the last stub
  339.          * The result is more or less similar to moving all the
  340.          * stubs above the one to be deleted, one place down.
  341.          * So, we must NOT increment 'i' !
  342.          */
  343.         result = true;
  344.         stubs->stubRecords[i] = stubs->stubRecords[stubs->numOfStubs-1];
  345.         pfree((Pointer)thisStub);
  346.         stubs->numOfStubs -=1;
  347.     } else {
  348.         /*
  349.          * examine the next stub...
  350.          */
  351.         i++;
  352.     }
  353.     }
  354.  
  355.     return(result);
  356. }
  357.  
  358.